/**
 * lsjs.suggest
 *
 * @require lsjs.js
 * @require lsjs.html.js
 * 
 * @author asuslx
*/

const STATE_FREE = 0;
const STATE_BUSY = 1;

lsjs.suggest = function(inputId, minLetters, controllerURL) {

    this.input = document.getElementById(inputId);
    this.input.autocomplete = "off";
    this.letters = minLetters;
    this.url = controllerURL;
    this.timeout = 1;
    this.state = STATE_FREE;

    this.onSend = function() {};
    this.onError = function() {};
    this.onComplete = function() {};

    this._onRequest = function (status, xhr, param) {
        switch(status) {

            case 'send':
                param.onSend.call(param);
                break;

            case 'complete':
                param._onData.call(param, xhr.responseText);
                param.onComplete.call(param);
                break;

            case 'error':
                param.onError.call(param);

                break;

            default :
                // invalid status
        }
    };

    this.request = function() {
        lsjs.transport.asyncRequest(this.url, 'POST', 'query='+this.input.value, this._onRequest, this);
    };

    this.listUp = function() {
        if(this.activeItem) {
            if(this.activeItem.previousSibling) {
                lsjs.css.remove(this.activeItem, 'active');
                this.activeItem = this.activeItem.previousSibling;
            }
        } else {
            var hint = document.getElementById("lsjs_suggest_hint");
            if(hint) {
                if(hint.lastChild) {
                    this.activeItem = hint.lastChild;
                }
            }
        }

        if(this.activeItem) {
            lsjs.css.add(this.activeItem, 'active');
            this.input.value = this.activeItem.innerHTML;
        }
    };

    this.listDown = function() {

        if(this.activeItem) {

            if(this.activeItem.nextSibling) {
                lsjs.css.remove(this.activeItem, 'active');
                this.activeItem = this.activeItem.nextSibling;
            }

        } else {

            var hint = document.getElementById("lsjs_suggest_hint");
            if(hint) {
                if(hint.firstChild) {
                    this.activeItem = hint.firstChild;
                }
            }
        }

         if(this.activeItem) {
             lsjs.css.add(this.activeItem, 'active');
             this.input.value = this.activeItem.innerHTML;
         }
    };

    this.keydown = function (evt) {

        if(evt.keyCode == 27) {
            // esc
            this.clear();
            return;
        }

        if(evt.keyCode == 38) {
            // up
            this.listUp();
            return;
        }

        if(evt.keyCode == 40) {
            // down
            this.listDown();
            return;
        }

    };

    this.keyup = function(evt) {

        // letters and space
        if(evt.keyCode == 38 || evt.keyCode == 40 || evt.keyCode == 27) return;

        if(this.input.value.length >=  this.letters) {
            
            if(this.state == STATE_FREE) {

                this.state = STATE_BUSY;
                setTimeout(function (obj) { return function () {obj.request.call(obj);}; } (this), this.timeout * 1000);
            }
        } else {
            this.clear();
        }
    };

    this.input.onkeydown = function (obj) {return function (evt) {obj.keydown.call(obj, evt)};} (this);

    this.input.onfocus = function (obj) {return function (evt) {obj.keyup.call(obj, evt)};} (this);
//    this.input.onblur = function (obj) {return function (evt) {obj.clear.call(obj)};} (this);

    this.input.onkeyup = function (obj) {return function (evt) {obj.keyup.call(obj, evt)};} (this);

    this.clear = function() {
        var hint = document.getElementById("lsjs_suggest_hint");
        if(hint) hint.innerHTML = '';
        this.activeItem = false;
    };

    this.select = function(text) {
        this.input.value = text;
        this.clear();
        this.input.form.submit();
    };

    this.item = function(text) {
        var li = lsjs.dom.create('li', {text: text});
        li.onclick = function (obj) {return function (evt) {obj.select.call(obj, evt.target.innerHTML)};} (this);
        return li;
    };

    this._onData = function(data) {

        var items;
        var html = '';
        eval("items = "+data+";");

        var hint = document.getElementById("lsjs_suggest_hint");
        if(!hint) {
            hint = lsjs.dom.create("ul", {id: "lsjs_suggest_hint", className: "lsjs-suggest"});
            lsjs.dom.insertAfter(hint, this.input);
        }
        hint.innerHTML = '';

        for(var i = 0; i < items.length; i++) {
            hint.appendChild(this.item(items[i]));
        }

        this.state = STATE_FREE;
        this.activeItem = false;
    };

    return this;
};